# -*- coding: utf-8 -*-
# @Time    : 2020/12/14 14:04
# @Author  : Guo_Zhanyu
# @File    : OmegaGo.py
from BoardBasics import *
from aiGzy2 import *
from PyQt5.QtCore import QTimer
import Choose
import requests


class BoardClient(BoardGUI):
    """
    Client
    """
    def __init__(self, lines):
        """
        Generate and Update a GUI, Connected with Server and Update timely.

        :param lines: The dimension of the board.
        """
        super(BoardClient, self).__init__(lines)
        self.who_am_i = None

        # 选择颜色的窗口
        self.Choose = QMainWindow()
        self.ChooseUI = Choose.Ui_MainWindow()
        self.ChooseUI.setupUi(self.Choose)
        self.ChooseUI.pushButton.clicked.connect(self.chooseBlack)
        self.ChooseUI.pushButton_2.clicked.connect(self.chooseWhite)
        self.Choose.show()

        # 获取的数据
        self.board_dict_get = dict()

        # 定时器，定时与服务器更新棋盘
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.operate)

        self.MainWindowUI.pushButton_2.clicked.connect(self.setPlayerMode)
        self.MainWindowUI.pushButton_3.clicked.connect(self.setAIMode)

        # 玩家 or AI模式
        self.mode = 0

        # AI类
        self.ai = None

        # 一些网络通信用参数
        self.id = 0
        self.state = 0  # 0: 初始化，1: 等待，2: 胜利
        pass

    def mousePressEvent(self, event):
        """
        Mouse press function.

        :param event: mouse event
        :return: None
        """
        if event.button() == Qt.LeftButton:
            if self.board.winner is None and self.board.cur_runner.name == self.who_am_i.name and self.mode == 0:
                # 如果没有胜者、当前轮次、玩家模式
                mouse_pos = [event.pos().x(), event.pos().y()]
                # 得到鼠标的棋盘位置
                click_point = self.getClickPoint(mouse_pos)

                # 在棋盘范围内
                if click_point is not None:
                    if self.board.canDrop(click_point):
                        self.board.drop(self.board.cur_runner, click_point)
                        self.board.cur_runner = self.board.getNextRunner(self.board.cur_runner)

                        # 提交
                        self.flaskPostBoard(click_point.x, click_point.y)
                        pass
                    pass
                else:
                    print('超过棋盘范围...')
                    pass
                self.update()
                pass
            pass
        pass

    def paintEvent(self, event):
        """
        Update graphically

        :param event: paint event
        :return: None
        """
        qp = QPainter(self)
        qp.begin(self)
        # 抗锯齿
        qp.setRenderHint(QPainter.Antialiasing)
        self.drawBoard(qp)  # 画棋盘
        self.drawStones(qp)  # 画棋子

        if self.state == 2:
            self.DialogUI.label.setText(f'{self.board.winner.name} 胜利，游戏结束，是否重新开始？')
            self.Dialog.show()
            pass

        qp.end()
        pass

    def regret(self):
        """
        Callback of regret button.

        :return: None
        """
        # 如果有步可以悔棋
        if self.board.history:
            board = self.board.getBoard()
            board[self.board.last.y][self.board.last.x] = 0
            self.board.setBoard(board)
            self.board.cur_runner = self.board.getNextRunner(self.board.cur_runner)

            self.board.history.pop(-1)
            if self.board.history:
                self.board.last = self.board.history[-1]
            else:
                self.board.last = None

            requests.get(self.url + 'rest/regret')
            self.update()
        else:
            print('Can not regret')
            pass

        pass

    def rerun(self):
        """
        Callback of Dialog OK button

        :return: None
        """
        # 提交重置棋盘申请
        self.flaskPostBoard(-1, -1)
        pass

    def notrerun(self):
        """
        Callback of Dialog Cancel button

        :return: None
        """
        # 没想好不继续要进行什么处理，暂且重开同样操作
        self.flaskPostBoard(-1, -1)
        pass

    def closeEvent(self, event):
        """
        Click on X (exit) callback.

        :param event:
        :return: None
        """
        # 提交重置棋盘申请
        self.flaskPostBoard(-1, -1)
        pass

    def setPlayerMode(self):
        """
        Callback of player mode.

        :return: None
        """
        self.mode = 0
        pass

    def setAIMode(self):
        """
        Callback of AI mode.

        :return: None
        """
        self.mode = 1
        pass

    def buttonFunc(self, ui):
        """
        Callback of MainWindow connect button

        :param ui: current ui -> MainWindow()
        :return: None
        """
        dataIn = ui.lineEdit.text()
        if dataIn != '':
            self.url = f'http://{dataIn}:5000/'
            pass
        ui.label_3.setText(self.url)
        self.flaskPostPlayer()

        # 开始定时器，T = 100ms
        self.timer.start(100)
        pass

    def chooseBlack(self):
        """
        Callback of ChooseUI black button.

        :return: None
        """
        self.who_am_i = BLACK_CHESSMAN
        self.ai = AI(self._lines, self.who_am_i)
        self.setWindowTitle('Omega Black')
        self.show()
        self.Choose.close()
        pass

    def chooseWhite(self):
        """
        Callback of ChooseUI white button.

        :return: None
        """
        self.who_am_i = WHITE_CHESSMAN
        self.ai = AI(self._lines, self.who_am_i)
        self.setWindowTitle('Omega White')
        self.show()
        self.Choose.close()
        pass

    def operate(self):
        """
        Timer.

        :return: None
        """
        try:
            # 从服务器获取信息
            self.flaskGetPlay()

            # 更新棋盘
            self.board.setBoard(self.board_dict_get['board'])
            self.ai.setBoard(self.board_dict_get['board'])

            # 更新当前轮次
            runner = self.board_dict_get['runner']
            if runner == 'black':
                self.board.cur_runner = BLACK_CHESSMAN
            elif runner == 'white':
                self.board.cur_runner = WHITE_CHESSMAN
                pass

            # 更新胜者
            win = self.board_dict_get['win']
            if win == 1:
                self.board.winner = BLACK_CHESSMAN
            elif win == 2:
                self.board.winner = WHITE_CHESSMAN
            else:
                self.board.winner = None
                pass

            # 更新游戏状态
            self.state = self.board_dict_get['newvalue']

            # 更新最后一步
            new_last = Point(self.board_dict_get['lastX'], self.board_dict_get['lastY'])
            if new_last.x != -1 and new_last.y != -1:
                self.board.last = new_last
                pass

            self.update()

            # AI下子
            if self.mode == 1 and self.board.cur_runner.name == self.who_am_i.name and self.board.winner is None:
                AI_point = self.ai.AI_drop()
                self.board.drop(self.who_am_i, AI_point)
                self.board.cur_runner = self.board.getNextRunner(self.board.cur_runner)
                self.board.last = AI_point
                # 提交
                self.flaskPostBoard(AI_point.x, AI_point.y)
                self.update()
                pass
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
            self.timer.stop()
        pass

    # def getBoardDictOnline(self):
    #     """
    #     Get Board Dict Online.
    #
    #     :return:
    #     """
    #     r1 = requests.get(self.url + 'board')
    #     self.board_dict_get = eval(r1.text)
    #     pass

    def flaskGetPlay(self):
        """
        flaskGetPlay.

        :return: None
        """
        try:
            r1 = requests.get(self.url + 'rest/play')
            self.board_dict_get = eval(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskGetState(self, newvalue):
        """
        flaskGetState

        :param newvalue: change state -> int()
        :return: None
        """
        try:
            r1 = requests.get(self.url + 'rest/play/state?={}'.format(newvalue))
            print(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskGetReport(self):
        """
        flaskGetReport

        :return: None
        """
        try:
            r1 = requests.get(self.url + 'rest/play/report')
            print(eval(r1.text)['report'])
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskGetPlayer(self):
        """
        flaskGetPlayer

        :return: None
        """
        try:
            r1 = requests.get(self.url + 'rest/player')
            print(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskPostPlayer(self):
        """
        flaskPostPlayer

        :return: None
        """
        try:
            post = dict()
            post['IP'] = self.getLocalIP()
            post['color'] = self.who_am_i.name
            r1 = requests.post(self.url + 'rest/player', data=post)
            self.id = eval(r1.text)['id']
            print(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskGetPlayerMsg(self, id):
        """
        flaskGetPlayerMsg

        :param id: player id -> int()
        :return: None
        """
        try:
            r1 = requests.get(self.url + 'rest/player/{}'.format(id))
            print(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    def flaskPostBoard(self, x, y):
        """
        flaskPostBoard

        :param x: stone's x -> int()
        :param y: stone's y -> int()
        :return: None
        """
        try:
            post = dict()
            post['id'] = self.id
            post['x'] = x
            post['y'] = y
            r1 = requests.post(self.url + 'rest/board', data=post)
            print(r1.text)
        except Exception as e:
            self.MainWindowUI.label_3.setText('连接失败...')
            print(e)
        pass

    # def postBoardDictOnline(self, x, y):
    #     """
    #
    #
    #     :param x:
    #     :param y:
    #     :return:
    #     """
    #     try:
    #         board_dict_post = dict()
    #         board_dict_post['x'] = x
    #         board_dict_post['y'] = y
    #
    #         r3 = requests.post(self.url + 'board', data=board_dict_post)
    #         print(str(datetime.datetime.now().strftime('%H:%M:%S')) + r3.text)
    #     except Exception as e:
    #         self.MainWindowUI.label_3.setText('连接失败...')
    #         print(e)
    #     pass
    #
    # pass


def main():
    client = QApplication(sys.argv)
    board_client = BoardClient(LINES)
    sys.exit(client.exec_())
    pass


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        print(e)
        pass
    pass
